package com.rhino.security.handler;

import com.alibaba.fastjson.JSON;
import com.rhino.security.constants.SecurityConstants;
import com.rhino.security.vo.RestResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 权限校验处理器，权限不足信息返回给前端:
 * Controller --Action添加注解@PreAuthorize("hasPermission('/test/name/**','Admin')") 时，当前访问用户没有权限
 * Spring Security @PreAuthorize 只能保证后端权限控制，不能控制前端权限；
 * 前端权限应该有一套逻辑，登录时，获取当前用户的角色和权限信息保存到前端；
 * 前端通过角色或权限展示某些菜单或按钮的显示，从而完成前端的权限控制；
 * 即使这样可能有用户会跳过前端的控制，直接调用后端接口，因此后端也需要有一套权限验证@PreAuthorize；
 */
@Slf4j
@Component
public class RestAccessDeniedHandler implements AccessDeniedHandler {

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        log.info("没有此权限：", accessDeniedException);
        response.setStatus(HttpStatus.METHOD_NOT_ALLOWED.value());
        response.setContentType(SecurityConstants.APPLICATION_JSON_UTF8_VALUE);
        PrintWriter writer = response.getWriter();

        //没有权限。一般用户 调用 管理员接口等问题
        RestResult result=RestResult.UNAUTH("请求被拒绝，前端控制权限有疏漏，前端需要做检查");
        writer.write(JSON.toJSONString(result));
        writer.close();
    }
}